﻿namespace OboutInc
{
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.IO;
    using System.Reflection;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;

    internal class Callback : Control
    {
        private string _event;
        private Type[] _numericTypes = new Type[] { typeof(byte), typeof(sbyte), typeof(decimal), typeof(double), typeof(float), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(short), typeof(ushort) };
        private oboutAJAXPage _Page;
        private bool _requestParsed;
        private bool _responseEnded;
        private bool _responseWritten;
        private Hashtable _values;
        private ArrayList scriptResponseList = new ArrayList();

        public Callback(oboutAJAXPage ContainerPage)
        {
            this.scriptResponseList.Add(new ScriptResponse(false));
            this.scriptResponseList.Add(new ScriptResponse(false));
            this._Page = ContainerPage;
        }

        internal void ClearScriptResponses()
        {
            this.scriptResponseList.Clear();
        }

        public ScriptResponse GetNewScriptResponse(bool keepLast)
        {
            ScriptResponse response = new ScriptResponse(keepLast);
            int num = this.scriptResponseList.Count - 1;
            if (!keepLast)
            {
                while (num > 1)
                {
                    if (!((ScriptResponse) this.scriptResponseList[num]).KeepLast)
                    {
                        break;
                    }
                    num--;
                }
            }
            if (num >= (this.scriptResponseList.Count - 1))
            {
                this.scriptResponseList.Add(response);
                return response;
            }
            this.scriptResponseList.Insert(num + 1, response);
            return response;
        }

        private void ParseRequest()
        {
            try
            {
                if (this.ContainerPage.IsFormPost)
                {
                    this._requestParsed = true;
                    this._event = "UpdatePanelOnPostback";
                    this._values = new Hashtable();
                }
                else
                {
                    CallbackData data = new CallbackData(this.ContainerPage.Request.InputStream);
                    this._requestParsed = true;
                    this._event = data.Event;
                    this._values = data.Values;
                }
            }
            catch (Exception exception)
            {
                this.ThrowException(exception.GetType().Name, exception.Message);
            }
        }

        internal string readScriptFromResource()
        {
            string str = "";
            MethodInfo[] methods = this.ContainerPage.GetType().GetMethods();
            for (int i = 0; i < methods.Length; i++)
            {
                JSVisible[] customAttributes = (JSVisible[]) methods[i].GetCustomAttributes(typeof(JSVisible), false);
                if (customAttributes.Length > 0)
                {
                    string str2 = "function " + methods[i].Name + "()";
                    string str3 = "";
                    ParameterInfo[] parameters = methods[i].GetParameters();
                    for (int j = 0; j < parameters.Length; j++)
                    {
                        string str4 = str3;
                        str3 = str4 + ((str3.Length == 0) ? "" : ",") + "\"" + parameters[j].Name + "\"";
                    }
                    string str5 = str2;
                    str2 = str5 + "{return ob_post_sp(\"" + methods[i].Name + "\",[" + str3 + "],arguments);}";
                    str = str + str2 + ";";
                }
            }
            return str;
        }

        private void RegisterForEventValidation(Control ctrl)
        {
            foreach (Control control in ctrl.Controls)
            {
                this.RegisterForEventValidation(control);
                this.Page.ClientScript.RegisterForEventValidation(control.UniqueID);
                this.Page.ClientScript.RegisterForEventValidation(control.ID);
                this.Page.ClientScript.RegisterForEventValidation(control.ClientID);
                this.Page.ClientScript.RegisterForEventValidation(ctrl.UniqueID);
                this.Page.ClientScript.RegisterForEventValidation(ctrl.ID);
                this.Page.ClientScript.RegisterForEventValidation(ctrl.ClientID);
            }
        }

        protected override void Render(HtmlTextWriter output)
        {
            this.RegisterForEventValidation(this);
            if (this.ContainerPage.IsCallback)
            {
                if (!this._responseWritten)
                {
                    this.ContainerPage.Response.Clear();
                    this.WriteResponse(false);
                }
            }
            else
            {
                this._Page.IsScriptRegistered = true;
                StringBuilder builder = new StringBuilder();
                builder.Append("<script type='text/javascript' language='JavaScript' src='" + this.ContainerPage.ServerFileNameNoParams + "?getScript=" + this.ContainerPage.ComponentVersion + "'></script>");
                builder.Append("<script type='text/javascript' language='JavaScript' src='" + this.ContainerPage.ClientScript.GetWebResourceUrl(base.GetType(), "OboutInc.Script.min.js") + "'></script>");
                builder.Append("<script type='text/javascript' language='JavaScript'>//<![CDATA[\r\n");
                builder.Append(string.Concat(new object[] { "var ob_post=new ob_post_Constructor(\"", Regex.Replace(this.ContainerPage.ServerFileName, @"(\?|&)getScript=[^&$]*", ""), "\",", this.ContainerPage.ShowErrorsAtClient.ToString().ToLower(), ",", this.ContainerPage.ThrowExceptionsAtClient.ToString().ToLower(), ",", this.ContainerPage.RequestTimeoutMilliseconds, ",", this.ContainerPage.AllowCSRFCheck ? "true" : "false", ");" }));
                builder.Append("\r\n//]]>\r\n</script>");
                output.Write(builder.ToString());
            }
        }

        internal void RenderOnLoadScript(HtmlTextWriter output)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("<script language=\"JavaScript\">\r\n//<![CDATA[\r\nvar fct=function(){" + ((ScriptResponse) this.scriptResponseList[1]).ResponseScript + "};fct();\r\n//]]>\r\n</script>");
            if (!this.ContainerPage.IsCallback && (((ScriptResponse) this.scriptResponseList[1]).ResponseScript != null))
            {
                output.Write(builder.ToString());
            }
        }

        public void ThrowException(string type, string message)
        {
            string[] strArray = new string[] { type, message };
            this.scriptResponseList.Clear();
            this.GetNewScriptResponse(false);
            this.Write(strArray);
            this.WriteScriptOnBeforeLoad("ob_post_ThrowException(response.content[0], response.content[1])");
            this.WriteResponse(true);
        }

        public void Write(object obj)
        {
            ((ScriptResponse) this.scriptResponseList[0]).WriteResponse(obj);
        }

        public void WriteResponse(bool endResponse)
        {
            if (this._responseEnded)
            {
                try
                {
                    this.ContainerPage.Response.Clear();
                }
                catch
                {
                }
            }
            else
            {
                if (this.ContainerPage.IsCallback)
                {
                    if ((this.ContainerPage.EnableSessionKeepAlive && (this.ContainerPage.Request.Cookies[this.ContainerPage.SessionCookieName] != null)) && (this.ContainerPage.Session.SessionID.Length > 0))
                    {
                        DateTime time = DateTime.Now.AddMinutes((double) this.ContainerPage.Session.Timeout);
                        HttpCookie cookie = this.ContainerPage.Response.Cookies[this.ContainerPage.SessionCookieName];
                        cookie.Value = this.ContainerPage.Session.SessionID;
                        cookie.Expires = time;
                        this.ContainerPage.Response.Cookies.Add(cookie);
                    }
                    if (FormsAuthentication.SlidingExpiration)
                    {
                        HttpCookie cookie2 = this.ContainerPage.Request.Cookies[FormsAuthentication.FormsCookieName];
                        FormsAuthenticationTicket tOld = null;
                        if (cookie2 != null)
                        {
                            try
                            {
                                tOld = FormsAuthentication.Decrypt(cookie2.Value);
                            }
                            catch
                            {
                                this.ContainerPage.Response.Cookies.Remove(cookie2.Name);
                            }
                            if ((tOld != null) && !tOld.Expired)
                            {
                                FormsAuthenticationTicket ticket = FormsAuthentication.RenewTicketIfOld(tOld);
                                if (ticket.Expiration != tOld.Expiration)
                                {
                                    string str = FormsAuthentication.Encrypt(ticket);
                                    cookie2.Expires = DateTime.Now.Add(ticket.Expiration.Subtract(ticket.IssueDate));
                                    cookie2.Value = str;
                                    cookie2.Secure = FormsAuthentication.RequireSSL;
                                    this.ContainerPage.Response.Cookies.Remove(cookie2.Name);
                                    this.ContainerPage.Response.Cookies.Add(cookie2);
                                }
                            }
                        }
                    }
                }
                if (this.ContainerPage.IsCallback)
                {
                    for (int i = 0; i < this.ContainerPage.Response.Cookies.Count; i++)
                    {
                        this.WriteScriptOnBeforeLoad(string.Concat(new object[] { "ob_post_createCookie(\"", this.ContainerPage.Response.Cookies[i].Name.Replace("\"", "\\\""), "\", \"", this.ContainerPage.Response.Cookies[i].Value.Replace("\"", "\\\""), "\", \"", this.ContainerPage.Response.Cookies[i].Expires.Subtract(DateTime.Now).TotalSeconds, "\")" }), true);
                    }
                }
                if (this.ContainerPage.IsCallback)
                {
                    try
                    {
                        this.ContainerPage.Response.Clear();
                    }
                    catch
                    {
                    }
                    try
                    {
                        this.ContainerPage.Response.ContentType = "text/xml";
                    }
                    catch
                    {
                    }
                    this.ContainerPage.Response.Write("<pbres>");
                    for (int j = 0; j < this.scriptResponseList.Count; j++)
                    {
                        this.ContainerPage.Response.Write(((ScriptResponse) this.scriptResponseList[j]).Render(j > 0));
                    }
                    this.ContainerPage.Response.Write("</pbres>");
                    this._responseWritten = true;
                }
                else
                {
                    StringWriter writer = new StringWriter();
                    HtmlTextWriter writer2 = new HtmlTextWriter(writer);
                    this.RenderControl(writer2);
                    if (endResponse)
                    {
                        this.RenderOnLoadScript(writer2);
                    }
                    writer2.Flush();
                    this.ContainerPage.Response.Write(writer.ToString());
                    writer.Close();
                    writer2.Close();
                }
                if (endResponse)
                {
                    try
                    {
                        this._responseEnded = true;
                        HttpContext.Current.Response.Flush();
                        HttpContext.Current.Response.End();
                    }
                    catch
                    {
                        HttpContext.Current.ApplicationInstance.CompleteRequest();
                    }
                }
            }
        }

        public void WriteScriptOnBeforeLoad(string str)
        {
            this.WriteScriptOnBeforeLoad(str, false);
        }

        private void WriteScriptOnBeforeLoad(string str, bool start)
        {
            ((ScriptResponse) this.scriptResponseList[0]).WriteScript(str, start);
        }

        internal void WriteScriptOnLoad(string str)
        {
            this.WriteScriptOnLoad(str, false, false);
        }

        internal void WriteScriptOnLoad(string str, bool userExplicit)
        {
            this.WriteScriptOnLoad(str, userExplicit, false);
        }

        private void WriteScriptOnLoad(string str, bool userExplicit, bool start)
        {
            ((ScriptResponse) this.scriptResponseList[1]).WriteScript(str, start);
            if (userExplicit)
            {
                ((ScriptResponse) this.scriptResponseList[1]).UserExplicit = true;
            }
        }

        private oboutAJAXPage ContainerPage
        {
            get
            {
                return this._Page;
            }
        }

        [Browsable(false)]
        public string Event
        {
            get
            {
                if (!this.ContainerPage.IsCallback)
                {
                    return null;
                }
                if (!this._requestParsed)
                {
                    this.ParseRequest();
                }
                return this._event;
            }
        }

        [Browsable(false)]
        public Hashtable Values
        {
            get
            {
                if (!this.ContainerPage.IsCallback)
                {
                    return null;
                }
                if (!this._requestParsed)
                {
                    this.ParseRequest();
                }
                return this._values;
            }
        }
    }
}

